/**
 ******************************************************************************
 * @file tcState_queue.c
 * @author GX (2524913364@qq.com)
 * @brief   链式队列,用户使用的时候直接将所有的前缀 "tcState_" 换成想要的就行了
 *          Function List:
                seqQueue *createQueue(void)         创建一个队列
                bool destroyQueue(seqQueue *que)    销毁队列
                bool inQueue(seqQueue *que, const void *item)   入队
                bool outQueue(seqQueue *que, void *item)    出队
                bool tcState_ergodicQueue(tcState_Queue_t *que)  遍历队列，该函数部分代码，
                                                            要用户自己实现
 * @version 1.0.1 
 * @date 2022-08-12
 * 
 * @copyright Copyright (c) 2022
 * 
 ******************************************************************************
 *----------------------------------------------------------------------------*
 *  Remark         : Description                                              *
 *----------------------------------------------------------------------------*
 *  Change History :                                                          *
 *  <Date>     | <Version> | <Author>       | <Description>                   *
 *----------------------------------------------------------------------------*
 *  2022-02-18 | 1.0.0     | GX             | Create file                     *
 *----------------------------------------------------------------------------*
 *  2022-08-18 | 1.0.1     | GX             | fix some bug                    *
 *----------------------------------------------------------------------------*
 *                                                                            *
 ******************************************************************************
 */

#include "tcState_queue.h"

/*创建队列*/
tcState_Queue_t *tcState_createQueue(void)
{
    tcState_Queue_t* que = malloc(sizeof(tcState_Queue_t));
    que->front = NULL;
    que->rear = NULL;
    que->size = 0;
    return que;
}

/*销毁队列*/
void tcState_destroyQueue(tcState_Queue_t *que)
{
    if(que == NULL) 
    {
        return;
    }

    tcState_datatype_t data;
    while(tcState_outQueue(que,  &data));
    free(que);
    que = NULL;
}

/*入队*/
bool tcState_inQueue(tcState_Queue_t *que, const void *item)
{
    /*检测是否为NULL*/
    if(que == NULL) 
    {
        return false;
    }
    /*检测队列是否满*/
    if(IS_FULL(que)) 
    {
        printf(">>>>>>>>>队满\n");
        tcState_datatype_t out_queue;
        tcState_outQueue(que, &out_queue);
    }

    /*创建数据节点*/
    tcState_node_t* tnode = malloc(sizeof(tcState_node_t)); 
    tnode->data = malloc(sizeof(tcState_datatype_t));
    memcpy(tnode->data, (tcState_datatype_t*)item, sizeof(tcState_datatype_t));
    tnode->next = NULL;

    /*如果队列为空， 就把头尾指向这个节点*/
    if(IS_EMPTY(que))
    {
        que->front = tnode;
        que->rear = tnode;
    }
    else
    {
        que->rear->next = tnode;
        que->rear = que->rear->next;
    }
    que->size++;
    return true;
}

/*出队*/
bool tcState_outQueue(tcState_Queue_t *que, void *item)
{
    /*检测是否为NULL*/
    if(que == NULL) 
    {
        return false;
    }
    /*检测队列是否空*/
    if(IS_EMPTY(que)) 
    {
        return false;
    }

    memcpy((tcState_datatype_t*)item, que->front->data,sizeof(tcState_datatype_t));
    tcState_node_t *pos = que->front;//暂存要出队列的节点
    que->front = que->front->next;//头指针往后移动
    if(que->front == NULL)
    {
        que->rear = NULL;//队列为空
    }

    //释放出队列的节点
    free(pos);
    que->size--;
    return true;
}


bool tcState_ergodicQueue(tcState_Queue_t *que)
{
    /*检测是否为NULL*/
    if(que == NULL) 
    {
        return false;
    }
    /*检测队列是否空*/
    if(IS_EMPTY(que)) 
    {
        return false;
    }

    tcState_node_t *tmpNode;
    tmpNode = que->front;
    while (tmpNode != NULL)
    {
        /* ********用户代码******** */
        // printf("%s\n", tmpNode->data->data);


        /* ********用户代码******** */

        tmpNode = tmpNode->next;
    }
    
    return true;
}